/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package niseeServlet.niseeAdmin;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import javax.imageio.ImageIO;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import niseeEntity.NiseeAnswer;
import niseeEntity.NiseeFormatGapsize;
import niseeEntity.NiseeImage;
import niseeEntity.NiseePercentageSize;
import niseeEntity.NiseeShape;
import niseeEntity.NiseeShapeCoor;
import niseeEntity.NiseeTestShape;
import niseeEntity.NiseeTestType;
import niseeImageGenerator.niShape;

/**
 *
 * @author Bing
 */
public class SaveShape extends HttpServlet {

    private EntityManagerFactory emf = null;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {


        HttpSession session = request.getSession(true);
        ArrayList<niShape> fore1 = (ArrayList) session.getAttribute("fore1");
        ArrayList<niShape> fore2 = (ArrayList) session.getAttribute("fore2");
        ArrayList<Short> percs = (ArrayList) session.getAttribute("percs");
        ArrayList<Short> sizes = (ArrayList) session.getAttribute("sizes");
        Short format = (Short) session.getAttribute("format");
        Short gapsize = (Short) session.getAttribute("gapsize");
        BufferedImage bufi = (BufferedImage) session.getAttribute("demo");
        String answer = (String) session.getAttribute("answer");
        int tesTypeId = (Integer) session.getAttribute("ttypeid");


//        session.removeAttribute("demo");
        session.removeAttribute("fore1");
        session.removeAttribute("fore2");
        session.removeAttribute("percs");
        session.removeAttribute("sizes");
        session.removeAttribute("format");
        session.removeAttribute("gapsize");

        EntityManager em = getEntityManager();

        NiseeShape niseeShape = new NiseeShape();
        niseeShape.setAnswer(answer);
        NiseeShape niseeShapeb = new NiseeShape();
        niseeShapeb.setAnswer(answer);
//        firstly we should create two  nisee shape as foreground a and b
        System.out.println("Going to persist nisee shape");
        em.getTransaction().begin();
        em.persist(niseeShape);
        em.persist(niseeShapeb);
        em.getTransaction().commit();
        System.out.println("Persistance finished: fore 1 id:" + niseeShape.getShapeID() + " fore 2 id:" + niseeShapeb.getShapeID());

        try {

//            secondly we should convert coors from fore to niseeShapeCoor
            Collection<NiseeShapeCoor> coors_a = new ArrayList<NiseeShapeCoor>();
            if (fore1 != null) {
                for (niShape x : fore1) {
//                    convert coor for fore1
                    NiseeShapeCoor niseeShapeCoor = new NiseeShapeCoor();
                    niseeShapeCoor.setCoorX(x.getX());
                    niseeShapeCoor.setCoorY(x.getY());
                    niseeShapeCoor.setScale(x.getScale());
                    niseeShapeCoor.setNiseeShape(niseeShape);
                    coors_a.add(niseeShapeCoor);
                }
            } else {
                System.err.println("No fore1");
            }
            Collection<NiseeShapeCoor> coors_b = new ArrayList<NiseeShapeCoor>();

            if (fore2 != null) {
                for (niShape x : fore2) {
//                  convert coor for fore2 NB. sometimes it's empty which means we have only one foreground
                    NiseeShapeCoor niseeShapeCoor = new NiseeShapeCoor();
                    niseeShapeCoor.setCoorX(x.getX());
                    niseeShapeCoor.setCoorY(x.getY());
                    niseeShapeCoor.setScale(x.getScale());
                    niseeShapeCoor.setNiseeShape(niseeShapeb);
                    coors_b.add(niseeShapeCoor);
                }
            } else {
                System.err.println("No fore1");
            }
            em = getEntityManager();
//            here set attach coors collections to corresponding nisee shape
            niseeShape.setNiseeShapeCoorCollection(coors_a);
            niseeShapeb.setNiseeShapeCoorCollection(coors_b);
            System.out.println("Going to update coors for nisee shape");
            em.getTransaction().begin();
//          here to persist two niseeshape which are foreground1 and foreground2
            NiseeShape a = em.find(NiseeShape.class, niseeShape.getShapeID());
            NiseeShape b = em.find(NiseeShape.class, niseeShapeb.getShapeID());
            a.setNiseeShapeCoorCollection(niseeShape.getNiseeShapeCoorCollection());
            b.setNiseeShapeCoorCollection(niseeShapeb.getNiseeShapeCoorCollection());
            em.getTransaction().commit();
            System.out.println("Updating coors finished");

//            query = em.createNativeQuery("select max(id) as rowcount from NiseeShapeCoor");
//            int shapeIdf2 = ((BigInteger) query.getSingleResult()).intValue();

//          here to get test type, prepare attach test shape to test type
            System.out.println("Locking Nisee test type... id " + tesTypeId);
            em = getEntityManager();
            em.getTransaction().begin();
            NiseeTestType niseeTType = em.find(NiseeTestType.class, tesTypeId);
            em.getTransaction().commit();
            System.out.println("Locked nisee test type ... id " + niseeTType.getTypeId());
            //niseeTestShape


            // create niseeTestShape , and attach two foregrounds to it
            NiseeTestShape niseeTestShape = new NiseeTestShape();
            niseeTestShape.setNiseeShape1(niseeShape);
            niseeTestShape.setNiseeShape(niseeShapeb);
//            bing, before you forgot to set this one, that's why we couldn't persist nisee test shape
            niseeTestShape.setNiseeTestType(niseeTType);
//            persist test shape
            System.out.println("Going to persist nisee test shape");
            em = getEntityManager();
            em.getTransaction().begin();
            em.persist(niseeTestShape);
            em.getTransaction().commit();
            System.out.println("Persistance nisee test shape finished " + niseeTestShape.getTestShapeId());


            int testShapeId = niseeTestShape.getTestShapeId();


            NiseeFormatGapsize niseeFormatGapsize = new NiseeFormatGapsize(testShapeId, gapsize, format);
            System.out.println("Going to persist nisee answer and gapsize");

            em.getTransaction().begin();
            String[] answers = answer.split(",");
            for (int i = 0; i < answers.length; i++) {
                NiseeAnswer niseeAnswer = new NiseeAnswer();
                niseeAnswer.setAnswer(answers[i]);
                niseeAnswer.setNiseeTestShape(niseeTestShape);
                em.persist(niseeAnswer);
            }
            em.persist(niseeFormatGapsize);

            for (int i = 0; i < sizes.size(); i++) {
                NiseePercentageSize niseePercentageSize = new NiseePercentageSize();
                niseePercentageSize.setNiseeTestShape(niseeTestShape);
                niseePercentageSize.setPercentages(percs.get(i));
                niseePercentageSize.setSize(sizes.get(i));
                em.persist(niseePercentageSize);
            }

            NiseeImage niseeImage = new NiseeImage();
            // O P E N
            ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);

            //WRITE
            ImageIO.write(bufi, "jpeg" /* "png" "jpeg" ... format desired */,
                    baos);

            //CLOSE
            baos.flush();
            byte[] resultImageAsRawBytes = baos.toByteArray();
            baos.close();

            niseeImage.setImageIMAGEFILE(resultImageAsRawBytes);
            niseeImage.setNiseeTestShape(niseeTestShape);
            em.persist(niseeImage);
//            NiseeTestType niseeTestType = new NiseeTestType();
            em.getTransaction().commit();

        } finally {
            em.close();
        }

    }

    private EntityManager getEntityManager() {
        if (emf == null) {
            emf = Persistence.createEntityManagerFactory("NiSeeFinalPU");
        }
        return emf.createEntityManager();
    }
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">

    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
